using System;
using System.Net.Http;
using System.Text;
using System.Text.Json;
using System.Threading.Tasks;

namespace WeatherMcpClient.Services
{
    public class WeatherService : IWeatherService
    {
        private readonly HttpClient _httpClient;
        private readonly string _baseUrl;

        public WeatherService(HttpClient httpClient, string baseUrl)
        {
            _httpClient = httpClient;
            _baseUrl = baseUrl.TrimEnd('/');
            _httpClient.DefaultRequestHeaders.Accept.Add(new System.Net.Http.Headers.MediaTypeWithQualityHeaderValue("application/json"));
            _httpClient.DefaultRequestHeaders.Accept.Add(new System.Net.Http.Headers.MediaTypeWithQualityHeaderValue("text/event-stream"));
        }

        public async Task<bool> CheckHealthAsync()
        {
            try
            {
                var response = await _httpClient.GetAsync($"{_baseUrl}/health");
                return response.IsSuccessStatusCode;
            }
            catch
            {
                return false;
            }
        }

        public async Task<string> GetCurrentWeatherAsync(double latitude, double longitude)
        {
            var requestData = new
            {
                jsonrpc = "2.0",
                id = Guid.NewGuid().ToString(),
                method = "tools/call",
                @params = new
                {
                    name = "get-current-weather",
                    arguments = new { latitude, longitude }
                }
            };

            return await PostAndExtractAsync(requestData);
        }

        public async Task<string> GetForecastAsync(double latitude, double longitude)
        {
            var requestData = new
            {
                jsonrpc = "2.0",
                id = Guid.NewGuid().ToString(),
                method = "tools/call",
                @params = new
                {
                    name = "get-forecast",
                    arguments = new { latitude, longitude }
                }
            };

            return await PostAndExtractAsync(requestData);
        }

        private async Task<string> PostAndExtractAsync(object requestData)
        {
            var content = new StringContent(JsonSerializer.Serialize(requestData), Encoding.UTF8, "application/json");
            var response = await _httpClient.PostAsync(_baseUrl, content);

            var result = await response.Content.ReadAsStringAsync();
            if (!response.IsSuccessStatusCode)
            {
                return $"请求失败: {(int)response.StatusCode} {response.StatusCode}\n{result}";
            }

            try
            {
                if (result.StartsWith("event: message", StringComparison.OrdinalIgnoreCase))
                {
                    var dataStart = result.IndexOf("data: ", StringComparison.Ordinal);
                    if (dataStart != -1)
                    {
                        var dataContent = result.Substring(dataStart + 6).Trim();
                        return ExtractFromMcpJson(dataContent);
                    }
                    return $"无法解析SSE响应:\n{result}";
                }

                return ExtractFromMcpJson(result);
            }
            catch (JsonException)
            {
                return $"解析JSON失败:\n{result}";
            }
        }

        private static string ExtractFromMcpJson(string json)
        {
            var jsonResult = JsonSerializer.Deserialize<JsonElement>(json);

            if (jsonResult.TryGetProperty("result", out var resultElement))
            {
                if (resultElement.TryGetProperty("content", out var contentElement))
                {
                    if (contentElement.ValueKind == JsonValueKind.Array && contentElement.GetArrayLength() > 0)
                    {
                        var firstContent = contentElement[0];
                        if (firstContent.ValueKind == JsonValueKind.Object && firstContent.TryGetProperty("text", out var textElement))
                        {
                            return textElement.GetString() ?? firstContent.ToString();
                        }
                        return firstContent.ToString();
                    }
                    return contentElement.ToString();
                }
                return resultElement.ToString();
            }

            if (jsonResult.TryGetProperty("error", out var errorElement))
            {
                return $"服务端错误: {errorElement}";
            }

            return json;
        }
    }
}

